package com.fingard.dsp.bank.directbank.cib01;

import com.fingard.constant.Format;
import com.fingard.crypto.SignVerifyHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IRealTime;
import com.fingard.dsp.bank.directbank.wjzf02.hessian.CCPMDownloadClient;
import com.fingard.dsp.bank.directbank.wjzf02.hessian.CCPMUploadClient;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import cacps.DownloadFileService;
import cacps.UploadFileService;
@Component("CIB01RealTime")
public class CIB01RealTime extends CIB01Base implements IRealTime {
	/** 
	 * 兴业银行渠道金联万家单笔实时代收业务提交
	 *  -- CommandCode:910803
	 *  -- 当前支持接入北京人保财实时收款
	 */
	public RetAtsSingle d_9108_RealTimeRec(ReqSingle p_req9108)	throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9108.reqHeader);
		
		ActSetItem actItem = getBankConfig().getActSetItem(p_req9108.singleDetail.recAct, "");
		String feeNO = getBankConfig().getMapValueByKey("feeNO9108", p_req9108.singleDetail.useType);
		
		boolean isChecked = true;
		String chkMsg = "";
		if (actItem == null) {
			isChecked = false;
			chkMsg = "未找到账号" + p_req9108.singleDetail.recAct + "的配置";
		}

		if (StringHelper.isNullOrEmpty(feeNO)) {
			isChecked = false;
			if (chkMsg.length() > 0) {
				chkMsg = chkMsg + "；";
			}
			chkMsg = "未找到代收费项代码";
		}
		
		if (!isChecked) {
			RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
			tmpRetDetail.respCode = "0";
			tmpRetDetail.respInfo = chkMsg;
			tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
			tmpRetDetail.transState = PaymentState.FAIL_Batch;
			tmpRetDetail.payInfoCode = "E9981";
			retAts.writeRetDetail(tmpRetDetail);
			return retAts;
		}
		
		String ownAct = p_req9108.singleDetail.recAct;
		if(StringHelper.hasAnyChar(actItem.actMapped)){
			ownAct = actItem.actMapped;
		}
		
		CIB01Header header = new CIB01Header();
		header.CorpNo = actItem.corpCode;
		header.Version = "V1.00";
		header.TranCode = "20602";//代收
		header.FeeNo = feeNO;
		
		// 发银行报文的XML对象
		XmlTextWriter xmlWriter = new XmlTextWriter();
		writeCommonHeader(xmlWriter, header);
		
		XElement tmpXElement = new XElement("In", "");
		tmpXElement.addChild(new XElement("SerialNum", p_req9108.singleDetail.askNumber));
		tmpXElement.addChild(new XElement("DbtrActName", p_req9108.singleDetail.payName));
		tmpXElement.addChild(new XElement("DbtrActId", p_req9108.singleDetail.payAct));
		tmpXElement.addChild(new XElement("DbtrCardType", "02"));// 没有字典
		String certType = this.convertCertTypeToBank(p_req9108.singleDetail.certType);
		tmpXElement.addChild(new XElement("DbtrCertType", certType));
		tmpXElement.addChild(new XElement("DbtrCertNo", p_req9108.singleDetail.certNum));
		tmpXElement.addChild(new XElement("DbtrBankType", p_req9108.singleDetail.payBankCode));// 银行类别
		tmpXElement.addChild(new XElement("DbtrBankId", p_req9108.singleDetail.cnapsCode));// 行号
		tmpXElement.addChild(new XElement("DbtrBankName", p_req9108.singleDetail.payBankName));
		tmpXElement.addChild(new XElement("CdtrActName", p_req9108.singleDetail.recName));
		tmpXElement.addChild(new XElement("CdtrActId", ownAct));
		tmpXElement.addChild(new XElement("PayAmt", p_req9108.singleDetail.payAmount));
		tmpXElement.addChild(new XElement("Remark", p_req9108.singleDetail.memo));
		tmpXElement.addChild(new XElement("Use", p_req9108.singleDetail.useType));
		xmlWriter.writeXElement(tmpXElement);
		xmlWriter.writeEndDocument();

		// CFCA证书加密
		String cerPath = actItem.oppCertFilePath;
		String pfxPath = actItem.ownKeyStorePath;
		
		SignVerifyHelper signVerifyHelper = new SignVerifyHelper();
		WriteBankLogStep2(xmlWriter.toXmlString());
		String signbyte = signVerifyHelper.signDateByCFCA(xmlWriter.toXmlString(), cerPath);
		String signStr = new BASE64Encoder().encode(signbyte.getBytes());
		
		CCPMUploadClient load = new CCPMUploadClient();
		UploadFileService service = load.getUploadFileService(bankFront.serverUpload);
		String returnXml1 = null;
		
		if(p_req9108.reqHeader.commandCode.equals("910803")){
			returnXml1 = service.asyncRealTimeSingle(actItem.userCode, actItem.corpCode, header.TranCode, signStr);
			WriteBankLogLn2("发送银行：" + "asyncRealTimeSingle 同步方法： " + "userCode :" + actItem.userCode + "  corpCode:" + actItem.corpCode
					+ " TranCode:" + header.TranCode + " signStr:" + signStr);
		}
		
		// 解密
		String str = new String(new BASE64Decoder().decodeBuffer(returnXml1));
		String returnXml = "";
		try {
			returnXml = signVerifyHelper.unEnvelopByCFCA(str, pfxPath, cerPath, actItem.ownKeyPassword);
		} catch (Exception e) {
			throw new Exception("验签返回报文失败");
		}
		WriteBankLogStep3(returnXml);
		RetAtsSglDetail tmpRetDetail = getDetailFromRetBkStr(returnXml);
		if (tmpRetDetail.respCode.equals("-1") || StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
			tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
		}
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**  -- 9144
	 * 兴业银行金联万家单笔实时代收业务状态查询
	 */
	public RetAtsSingle d_9144_QryRealTimeRec(ReqQrySingle p_req9144) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9144.reqHeader);
		RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();

		ActSetItem actItem = getBankConfig().getActSetItem(p_req9144.recAct, "");
		String feeNO = getBankConfig().getMapValueByKey("feeNO9108", "");
		
		boolean isChecked = true;
		String chkMsg = "";
		if (actItem == null) {
			isChecked = false;
			chkMsg = "未找到账号" + p_req9144.recAct + "的配置";
		}
		
		if (StringHelper.isNullOrEmpty(feeNO)) {
			isChecked = false;
			if (chkMsg.length() > 0) {
				chkMsg = chkMsg + "；";
			}
			chkMsg = "未找到代收费项代码";
		}
		
		if (!isChecked) {
			RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
			tmpRetDetail.respCode = "0";
			tmpRetDetail.respInfo = chkMsg;
			tmpRetDetail.reqSeqID = p_req9144.askNumber;
			tmpRetDetail.transState = PaymentState.FAIL_Batch;
			tmpRetDetail.payInfoCode = "E9981";
			retAts.writeRetDetail(tmpRetDetail);
			return retAts;
		}
		
		String corpNo = actItem.corpCode;
		String bizDate = Format.Date8Format.format(p_req9144.getBgnDateTime());
		String tranCode = "20602";
		String feeNo = feeNO;
		String serialNum = p_req9144.askNumber;
		
		CCPMDownloadClient cdownload = new CCPMDownloadClient();
		DownloadFileService tmpService = cdownload.getDownloadFileService(bankFront.serverDownload);
		String tmpBankRet = tmpService.queryRealTimeSingleBySerialNum(corpNo, bizDate, tranCode, feeNo, serialNum);
		WriteBankLogLn2("发送银行：" + "queryRealTimeSingleBySerialNum 查询方法： " + "corpNo :" + corpNo + "  bizDate:" + bizDate
				+ " tranCode:" + tranCode + " feeNo:" + feeNO + "serialNum:" + serialNum);
		WriteBankLogStep3(tmpBankRet);
		tmpRetAtsDetail = getDetailFromRetBkStr(tmpBankRet);
		if (tmpRetAtsDetail.respCode.equals("-1") || StringHelper.isNullOrEmpty(tmpRetAtsDetail.reqSeqID)) {
			tmpRetAtsDetail.reqSeqID = p_req9144.askNumber;
		}
		retAts.writeRetDetail(tmpRetAtsDetail);
		return retAts;
	}
	
	private RetAtsSglDetail getDetailFromRetBkStr(String p_retBkStr) throws Exception {
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.respCode = "-1";
		StringBuilder tmpSbMsg = new StringBuilder();
		// 解析银行返回
		XmlTextReader tmpBkReader = loadBankRespXmlReader(p_retBkStr, tmpSbMsg);
		if (tmpBkReader != null) {
			String tmpRetCode = tmpBkReader.getFirstText("/Message/Head/ResFlag");
			tmpRetDetail.respCode = "0";
			if (tmpRetCode.equals("0")) {
				tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Message/Head/ErrorMsg");
				tmpRetDetail.transState = tmpRetCode + "+" + tmpBkReader.getFirstText("/Message/Head/ErrorCode");
				tmpRetDetail.payInfoCode = tmpRetDetail.transState;
			} else if (tmpRetCode.equals("1")) {
				tmpRetDetail.reqSeqID = tmpBkReader.getFirstText("/Message/Out/SerialNum");
				tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Message/Out/RetMsg");
				tmpRetDetail.transState = tmpRetCode + "+" + tmpBkReader.getFirstText("/Message/Out/RetCode");
				tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Message/Out/RetCode");
				if(StringHelper.hasAnyChar(tmpRetDetail.respInfo)){
					if(tmpRetDetail.respInfo.indexOf("-") > 0){
						String[] tmpPickStr = tmpRetDetail.respInfo.split("-");
						if(StringHelper.hasAnyChar(tmpPickStr[0])){
							tmpRetDetail.payInfoCode = tmpPickStr[0];
						}
						else{
							tmpRetDetail.payInfoCode = tmpRetDetail.respInfo;
						}
					}
					else{
						tmpRetDetail.payInfoCode = tmpRetDetail.respInfo;
					}
				}
			}
		} else {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = tmpSbMsg.toString();
		}
		return tmpRetDetail;
	}
}
